/**
 * 
 */
package name.marz.to.go.btree;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

import name.marz.to.go.btree.node.ArrayNode;
import name.marz.to.go.btree.node.BTree;
import name.marz.to.go.btree.node.Key;
import name.marz.to.go.btree.node.Node;
import name.marz.to.go.btree.node.NodeFactory;
import name.marz.to.go.btree.node.TreeMapNode;
import name.marz.to.go.btree.ui.swing.ControlPanel;
import name.marz.to.go.btree.ui.swing.GraphicsConfigration;
import name.marz.to.go.btree.ui.swing.SelectControlPanel;
import name.marz.to.go.btree.ui.swing.TreePanel;



/**
 * @author masaru-gotou
 *
 */
public class BTreeDemo extends Applet {
	private ControlPanel controlPanel;
	private TreePanel treePanel;
	private JFrame mainFrame;
	private BTree<?> tree;
	private LinkedList<Node> history = new LinkedList<Node>();
	private int currHistIdx;
	
	// TODO:Appletにおけるちらつき対応
	
	public BTreeDemo() {
		super();
	}
	
	public BTreeDemo(String title) {
		//　フレームを生成
		mainFrame = new JFrame(title);
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// パネルを生成
		JPanel panel = new JPanel(new BorderLayout());
		panel.setOpaque(true);
		
//		controlPanel = new ControlPanel();
//		controlPanel.getInitPanel().addInitActionListener(new InitActionListener());
//		controlPanel.getInsertPanel().addInsertActionListener(new InsertActionListener());
//		controlPanel.getSelectPanel().addSelectActionListener(new SelectActionListener());
//		controlPanel.getSelectPanel().setSelectButtonEnabled(false);
//		controlPanel.getSnapPanel().addSnapActionListener(new SnapActionListener());
//		controlPanel.getSnapPanel().addNextActionListener(new NextActionListener());
//		controlPanel.getSnapPanel().addPrevActionListener(new PrevActionListener());
		createControlPanel();
		
		treePanel = new TreePanel(GraphicsConfigration.getInstance());
//		treePanel.setBorder(BorderFactory.createTitledBorder("Tree"));
		JScrollPane scrollpane = new JScrollPane(treePanel);

		panel.add(BorderLayout.WEST, controlPanel);
		panel.add(BorderLayout.CENTER, scrollpane);
		
		// フレームにパネルをセット
		mainFrame.setContentPane(panel);
		
		mainFrame.pack();
	}
	
	private class NextActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			
			currHistIdx++;
		}
	}
	private class PrevActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			tree.setRoot(history.get(--currHistIdx));
			treePanel.repaint();
		}
	}
	private class SelectActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			SelectControlPanel panel = controlPanel.getSelectPanel();
			Object result =	(Object)(tree.search(new Key(
					Integer.parseInt(panel.getKey()))
			));
			if ( result == null ) {
				panel.setResult("not found");
			} else {
				panel.setResult(result.toString());
			}
		}
	}
	private class InitActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if ( controlPanel.getInitPanel().isInitDefaultSelected() ) initTreeDefault();
			if ( controlPanel.getInitPanel().isInitRandomSelected() ) initTreeRandom();
			if ( controlPanel.getInitPanel().isInitSequenceSelected() ) initTreeSequencial();
			history.clear();
			history.addFirst(tree.getRoot());
			currHistIdx = 0;
		}
	}
	private class SnapActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO スナップショット機能実装
		}

	}
	
	private void initTreeDefault() {
		DemoTreeBuilder builder = new DemoTreeBuilder();
		tree = builder.buildTree();
		treePanel.setTree(tree);
		treePanel.repaint();
		controlPanel.getSelectPanel().setSelectButtonEnabled(true);
	}
	private void initTreeRandom() {
		int keys = controlPanel.getInitPanel().getKeyCountInNode();
		int records = controlPanel.getInitPanel().getRecordCount();
		tree = new BTree<String>(NodeFactory.createNode(ArrayNode.class.getName() ,keys));
		for ( int i=0; i< records;i++ ) {
			int value = (int)(Math.random() * 100);
			tree.insert(new Key(value), "Data"+value);
		}
		treePanel.setTree(tree);
		treePanel.repaint();
		controlPanel.getSelectPanel().setSelectButtonEnabled(true);
	}
	private void initTreeSequencial() {
		int keys = controlPanel.getInitPanel().getKeyCountInNode();
		int records = controlPanel.getInitPanel().getRecordCount();
//		tree = new BTree<String>(new TreeMapNode(keys));
		tree = new BTree<String>(NodeFactory.createNode(TreeMapNode.class.getName(), keys));
		for ( int i=1; i<=records;i++ ) {
			tree.insert(new Key(i*10), "Data"+i);
		}
		treePanel.setTree(tree);
		treePanel.repaint();
		controlPanel.getSelectPanel().setSelectButtonEnabled(true);
	}
	
	private class InsertActionListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			Key key = new Key(Integer.parseInt(controlPanel.getInsertPanel().getKey()));
			String value = controlPanel.getInsertPanel().getValue();
			tree.insert(key, value);
			try {
				history.add((Node)tree.getRoot().clone());
				currHistIdx++;
			} catch (CloneNotSupportedException ex) {
				System.err.println(ex);
			}
			treePanel.repaint();
		}
		
	}
	
	private class DeleteActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO:削除機能実装
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				BTreeDemo main = new BTreeDemo("BTree Demo");
				main.mainFrame.setVisible(true);
			}
		});
	}
	
	@Override
	public void init() {
		createControlPanel();
		createTreePanel();
		
		add( controlPanel,BorderLayout.WEST);
		add( new JScrollPane(treePanel), BorderLayout.CENTER);
		
	}
	private void createTreePanel() {
		treePanel = new TreePanel(GraphicsConfigration.getInstance());
	}

	private void createControlPanel() {
		controlPanel = new ControlPanel();
		controlPanel.getInitPanel().addInitActionListener(new InitActionListener());
		controlPanel.getInsertPanel().addInsertActionListener(new InsertActionListener());
		controlPanel.getSelectPanel().addSelectActionListener(new SelectActionListener());
		controlPanel.getSelectPanel().setSelectButtonEnabled(false);
		controlPanel.getDeletePanel().addDeleteActionListener(new DeleteActionListener());
		controlPanel.getSnapPanel().addSnapActionListener(new SnapActionListener());
		controlPanel.getSnapPanel().addNextActionListener(new NextActionListener());
		controlPanel.getSnapPanel().addPrevActionListener(new PrevActionListener());
	}
	@Override
	public void destroy() {
		super.destroy();
	}
	@Override
	public void start() {
		super.start();
	}
	@Override
	public void stop() {
		super.stop();
	}

}
